package com.papercutting.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.papercutting.platform.dto.response.UserStudyResponse;
import com.papercutting.platform.entity.Tutorial;
import com.papercutting.platform.entity.UserStudy;
import com.papercutting.platform.repository.UserStudyRepository;
import com.papercutting.platform.service.TutorialService;
import com.papercutting.platform.service.UserStudyService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户学习记录服务实现类
 */
@Service
@RequiredArgsConstructor
public class UserStudyServiceImpl implements UserStudyService {
    
    private final UserStudyRepository userStudyRepository;
    private final TutorialService tutorialService;
    
    @Override
    public UserStudy save(UserStudy userStudy) {
        if (userStudy.getId() == null) {
            userStudyRepository.insert(userStudy);
        } else {
            userStudyRepository.updateById(userStudy);
        }
        return userStudy;
    }
    
    @Override
    public UserStudy findById(Long id) {
        return userStudyRepository.selectById(id);
    }
    
    @Override
    public List<UserStudy> findAll() {
        return userStudyRepository.selectList(null);
    }
    
    @Override
    public Page<UserStudy> findAll(Pageable pageable) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<UserStudy> page =
            new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(
                pageable.getPageNumber() + 1, pageable.getPageSize());
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<UserStudy> result =
            userStudyRepository.selectPage(page, null);
        return new PageImpl<>(result.getRecords(), pageable, result.getTotal());
    }
    
    @Override
    public void deleteById(Long id) {
        userStudyRepository.deleteById(id);
    }
    
    @Override
    public List<UserStudy> findByUserId(Long userId) {
        QueryWrapper<UserStudy> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        return userStudyRepository.selectList(wrapper);
    }

    @Override
    public List<UserStudy> findByTutorialId(Long tutorialId) {
        QueryWrapper<UserStudy> wrapper = new QueryWrapper<>();
        wrapper.eq("tutorial_id", tutorialId);
        return userStudyRepository.selectList(wrapper);
    }

    @Override
    public UserStudy findByUserIdAndTutorialId(Long userId, Long tutorialId) {
        QueryWrapper<UserStudy> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("tutorial_id", tutorialId);
        return userStudyRepository.selectOne(wrapper);
    }

    @Override
    public List<UserStudy> findByIsCompleted(Boolean isCompleted) {
        QueryWrapper<UserStudy> wrapper = new QueryWrapper<>();
        wrapper.eq("is_completed", isCompleted);
        return userStudyRepository.selectList(wrapper);
    }

    @Override
    public List<UserStudy> findByUserIdAndIsCompleted(Long userId, Boolean isCompleted) {
        QueryWrapper<UserStudy> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("is_completed", isCompleted);
        return userStudyRepository.selectList(wrapper);
    }
    
    @Override
    public Page<UserStudy> findUserStudyList(Long userId, Pageable pageable) {
        List<UserStudy> userStudies = findByUserId(userId);
        
        // 分页处理
        int start = (int) pageable.getOffset();
        int end = Math.min(start + pageable.getPageSize(), userStudies.size());
        List<UserStudy> pageContent = start <= end && start < userStudies.size() ? 
            userStudies.subList(start, end) : List.of();
            
        return new PageImpl<>(pageContent, pageable, userStudies.size());
    }
    
    @Override
    public Page<UserStudyResponse> findUserStudyListWithTutorial(Long userId, Pageable pageable) {
        List<UserStudy> userStudies = findByUserId(userId);
        
        // 获取所有教程信息
        List<Tutorial> allTutorials = tutorialService.findAll();
        Map<Long, Tutorial> tutorialMap = allTutorials.stream()
            .collect(Collectors.toMap(Tutorial::getId, tutorial -> tutorial));
        
        // 转换为响应对象并填充教程信息
        List<UserStudyResponse> responseList = userStudies.stream()
            .map(userStudy -> {
                UserStudyResponse response = new UserStudyResponse();
                BeanUtils.copyProperties(userStudy, response);
                
                // 设置教程信息
                Tutorial tutorial = tutorialMap.get(userStudy.getTutorialId());
                if (tutorial != null) {
                    UserStudyResponse.TutorialInfo tutorialInfo = new UserStudyResponse.TutorialInfo();
                    tutorialInfo.setId(tutorial.getId());
                    tutorialInfo.setTitle(tutorial.getTitle());
                    tutorialInfo.setSubtitle(tutorial.getSubtitle());
                    tutorialInfo.setCoverImage(tutorial.getCoverImage());
                    tutorialInfo.setSummary(tutorial.getSummary());
                    tutorialInfo.setDifficultyLevel(tutorial.getDifficultyLevel());
                    tutorialInfo.setCategory(tutorial.getCategory());
                    tutorialInfo.setEstimatedTime(tutorial.getEstimatedTime());
                    tutorialInfo.setStepsCount(tutorial.getStepsCount());
                    tutorialInfo.setViewCount(tutorial.getViewCount());
                    tutorialInfo.setLikeCount(tutorial.getLikeCount());
                    tutorialInfo.setFavoriteCount(tutorial.getFavoriteCount());
                    response.setTutorial(tutorialInfo);
                }
                
                return response;
            })
            .collect(Collectors.toList());
        
        // 分页处理
        int start = (int) pageable.getOffset();
        int end = Math.min(start + pageable.getPageSize(), responseList.size());
        List<UserStudyResponse> pageContent = start <= end && start < responseList.size() ? 
            responseList.subList(start, end) : List.of();
            
        return new PageImpl<>(pageContent, pageable, responseList.size());
    }
    
    @Override
    public Map<String, Object> getStudyProgress(Long userId) {
        List<UserStudy> studyRecords = findByUserId(userId);
        
        Map<String, Object> stats = new HashMap<>();
        
        // 基本统计
        stats.put("totalTutorials", studyRecords.size());
        
        long completedTutorials = studyRecords.stream()
            .filter(UserStudy::getIsCompleted)
            .count();
        stats.put("completedTutorials", completedTutorials);
        
        // 学习中的教程数
        long learningTutorials = studyRecords.stream()
            .filter(study -> !study.getIsCompleted() && study.getProgress() > 0)
            .count();
        stats.put("learningTutorials", learningTutorials);
        
        // 未开始的教程数
        long notStartedTutorials = studyRecords.stream()
            .filter(study -> study.getProgress() == 0)
            .count();
        stats.put("notStartedTutorials", notStartedTutorials);
        
        // 计算总学习时长
        int totalStudyTime = studyRecords.stream()
            .mapToInt(UserStudy::getStudyDuration)
            .sum();
        stats.put("totalStudyTime", totalStudyTime);
        
        // 计算平均进度
        if (!studyRecords.isEmpty()) {
            double avgProgress = studyRecords.stream()
                .mapToInt(UserStudy::getProgress)
                .average()
                .orElse(0.0);
            stats.put("averageProgress", Math.round(avgProgress));
        } else {
            stats.put("averageProgress", 0);
        }
        
        // 计算完成率
        if (!studyRecords.isEmpty()) {
            double completionRate = (completedTutorials * 100.0) / studyRecords.size();
            stats.put("completionRate", Math.round(completionRate));
        } else {
            stats.put("completionRate", 0);
        }
        
        // 最近学习记录
        stats.put("recentStudies", studyRecords.stream()
            .sorted((a, b) -> {
                if (a.getLastStudyTime() == null) return 1;
                if (b.getLastStudyTime() == null) return -1;
                return b.getLastStudyTime().compareTo(a.getLastStudyTime());
            })
            .limit(5)
            .collect(java.util.stream.Collectors.toList()));
        
        return stats;
    }
}